package com.moxiao.yfjh.module.activity.service.activityEnroll;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.moxiao.yfjh.framework.common.pojo.PageResult;
import com.moxiao.yfjh.framework.common.util.number.NoCommonUtil;
import com.moxiao.yfjh.framework.ip.core.utils.AreaUtils;
import com.moxiao.yfjh.framework.mybatis.core.util.MyBatisUtils;
import com.moxiao.yfjh.framework.pay.core.client.dto.order.PayOrderRespDTO;
import com.moxiao.yfjh.framework.pay.core.client.dto.refund.PayRefundRespDTO;
import com.moxiao.yfjh.framework.pay.core.enums.order.PayOrderStatusRespEnum;
import com.moxiao.yfjh.framework.pay.core.enums.refund.PayRefundStatusRespEnum;
import com.moxiao.yfjh.module.activity.controller.admin.activityEnroll.vo.*;
import com.moxiao.yfjh.module.activity.controller.admin.activityPackage.vo.ActivityPackageExportReqVO;
import com.moxiao.yfjh.module.activity.controller.admin.activityenrollverificate.vo.ActivityEnrollVerificateCreateReqVO;
import com.moxiao.yfjh.module.activity.controller.app.vo.AppActivityInfoVo;
import com.moxiao.yfjh.module.activity.controller.app.vo.AppEnrollUseVO;
import com.moxiao.yfjh.module.activity.convert.activityEnroll.ActivityEnrollConvert;
import com.moxiao.yfjh.module.activity.dal.dataobject.activityEnroll.ActivityEnrollDO;
import com.moxiao.yfjh.module.activity.dal.dataobject.activityInfo.ActivityInfoDO;
import com.moxiao.yfjh.module.activity.dal.dataobject.activityPackage.ActivityPackageDO;
import com.moxiao.yfjh.module.activity.dal.dataobject.productInfo.ProductInfoDO;
import com.moxiao.yfjh.module.activity.dal.mysql.activityEnroll.ActivityEnrollMapper;
import com.moxiao.yfjh.module.activity.dal.mysql.activityInfo.ActivityInfoMapper;
import com.moxiao.yfjh.module.activity.dal.mysql.activityenrollverificate.ActivityEnrollVerificateMapper;
import com.moxiao.yfjh.module.activity.service.activityPackage.ActivityPackageService;
import com.moxiao.yfjh.module.activity.service.activityenrollverificate.ActivityEnrollVerificateService;
import com.moxiao.yfjh.module.activity.service.productInfo.ProductInfoService;
import com.moxiao.yfjh.module.blind.controller.admin.memberusertag.vo.MemberUsertagExportReqVO;
import com.moxiao.yfjh.module.blind.dal.dataobject.member.BlindMemberUserDO;
import com.moxiao.yfjh.module.blind.dal.dataobject.memberusertag.MemberUsertagDO;
import com.moxiao.yfjh.module.blind.service.member.BlindMemberUserService;
import com.moxiao.yfjh.module.blind.service.memberusertag.MemberUsertagService;
import com.moxiao.yfjh.module.pay.api.order.dto.PayOrderCreateReqDTO;
import com.moxiao.yfjh.module.pay.controller.admin.order.vo.PayOrderSubmitRespVO;
import com.moxiao.yfjh.module.pay.controller.app.order.vo.AppPayOrderSubmitReqVO;
import com.moxiao.yfjh.module.pay.dal.dataobject.app.PayAppDO;
import com.moxiao.yfjh.module.pay.dal.dataobject.channel.PayChannelDO;
import com.moxiao.yfjh.module.pay.dal.dataobject.order.PayOrderDO;
import com.moxiao.yfjh.module.pay.dal.dataobject.order.PayOrderExtensionDO;
import com.moxiao.yfjh.module.pay.dal.dataobject.refund.PayRefundDO;
import com.moxiao.yfjh.module.pay.dal.mysql.order.PayOrderExtensionMapper;
import com.moxiao.yfjh.module.pay.dal.mysql.order.PayOrderMapper;
import com.moxiao.yfjh.module.pay.dal.mysql.refund.PayRefundMapper;
import com.moxiao.yfjh.module.pay.dal.redis.no.PayNoRedisDAO;
import com.moxiao.yfjh.module.pay.enums.order.PayOrderStatusEnum;
import com.moxiao.yfjh.module.pay.enums.order.PayOrderTypeEnum;
import com.moxiao.yfjh.module.pay.framework.pay.config.PayProperties;
import com.moxiao.yfjh.module.pay.service.app.PayAppService;
import com.moxiao.yfjh.module.pay.service.channel.PayChannelService;
import com.moxiao.yfjh.module.pay.service.notify.PayNotifyService;
import com.moxiao.yfjh.module.pay.service.order.PayOrderService;
import com.moxiao.yfjh.module.system.service.dict.DictDataService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.moxiao.yfjh.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.moxiao.yfjh.framework.common.util.json.JsonUtils.toJsonString;
import static com.moxiao.yfjh.framework.common.util.servlet.ServletUtils.getClientIP;
import static com.moxiao.yfjh.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static com.moxiao.yfjh.module.activity.enums.ErrorCodeConstants.*;
import static com.moxiao.yfjh.module.pay.enums.ErrorCodeConstants.PAY_ORDER_EXTENSION_NOT_FOUND;
import static com.moxiao.yfjh.module.pay.enums.ErrorCodeConstants.PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING;

/**
 * 相亲报名信息 Service 实现类
 *
 * @author mx
 */
@Service
@Validated
@Slf4j
public class ActivityEnrollServiceImpl implements ActivityEnrollService {

    @Resource
    private ActivityEnrollMapper enrollMapper;
    @Resource
    private ActivityInfoMapper activityInfoMapper;
    @Resource
    private ActivityPackageService packageService;
    @Resource
    private ActivityEnrollVerificateService verificateService;
    @Resource
    private ActivityEnrollVerificateMapper verificateMapper;
    @Resource
    private DictDataService dictDataService;
    @Resource
    private ProductInfoService productInfoService;
    @Resource
    private PayOrderService payOrderService;
    @Resource
    private PayAppService payAppService;
    @Resource
    private BlindMemberUserService memberUserService;
    @Resource
    private PayProperties payProperties;
    @Resource
    private PayOrderMapper orderMapper;
    @Resource
    private PayOrderExtensionMapper orderExtensionMapper;
    @Resource
    private PayNoRedisDAO noRedisDAO;
    @Resource
    private PayAppService appService;
    @Resource
    private PayChannelService channelService;
    @Resource
    private PayNotifyService notifyService;
    @Resource
    private PayRefundMapper refundMapper;

    @Resource
    private MemberUsertagService usertagService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createEnroll(ActivityEnrollCreateReqVO createReqVO) {
        //TODO 为传值时，添加默认值
        if (createReqVO.getStatus() == null) {
            // 0=已报名
            createReqVO.setStatus((byte) 0);
        }
        // 是否是被选择成为活动人员:0=是，1=否
        if (createReqVO.getActivityStatus() == null) {
            createReqVO.setActivityStatus((byte) 1);
        }
        // 是否配对:0=是，1=否（不用配对）
        if (createReqVO.getIsPair() == null) {
            createReqVO.setIsPair((byte) 1);
            createReqVO.setSelected((byte) 0);
        }

        // 插入
        ActivityEnrollDO enroll = ActivityEnrollConvert.INSTANCE.convert(createReqVO);
        enrollMapper.insert(enroll);
        // 根据活动id查询活动下的商品信息
        if (Objects.nonNull(enroll.getId())) {
            ActivityPackageExportReqVO packageQuery = new ActivityPackageExportReqVO();
            packageQuery.setActiveId(createReqVO.getActivityId());
            List<ActivityPackageDO> packageDOList = packageService.getPackageList(packageQuery);
            if (packageDOList.size() > 0) {
                packageDOList.stream().forEach(item -> {
                    //保存相亲报名子表详情信息
                    ActivityEnrollVerificateCreateReqVO createVerificate = new ActivityEnrollVerificateCreateReqVO();
                    createVerificate.setActivityId(item.getActiveId());
                    createVerificate.setActivityProductsId(item.getProductId());
                    createVerificate.setUserId(createReqVO.getUserId());
                    createVerificate.setEnrollId(enroll.getId());
                    // 获得单个商品的单价
                    ProductInfoDO productInfoDO = productInfoService.getProductInfo(item.getProductId());
                    createVerificate.setPrice(new BigDecimal(productInfoDO.getPlatformPrice()));
                    Integer code = getReaptCode();
                    createVerificate.setVerificationCode(String.valueOf(code));
                    createVerificate.setStatus((byte) 0);
                    createVerificate.setType((byte) 0);
                    verificateService.createEnrollVerificate(createVerificate);
                });
            } else {
                throw exception(ENROLL_PACKAGE_PRODUCT_NOT_EXISTS);
            }
        }
        // 返回
        return enroll.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ActivityEnrollDO createAppEnroll(ActivityEnrollCreateReqVO createReqVO) {
        try {
            //TODO 为传值时，添加默认值
            if (createReqVO.getStatus() == null) {
                // 0=已报名
                createReqVO.setStatus((byte) 0);
            }
            // 是否是被选择成为活动人员:0=是，1=否
            if (createReqVO.getActivityStatus() == null) {
                createReqVO.setActivityStatus((byte) 1);
            }
            // 是否配对:0=是，1=否（不用配对）
            if (createReqVO.getIsPair() == null) {
                createReqVO.setIsPair((byte) 1);
                createReqVO.setSelected((byte) 0);
            }
            // 插入
            ActivityEnrollDO enroll = ActivityEnrollConvert.INSTANCE.convert(createReqVO);
            enrollMapper.insert(enroll);
            // 根据活动id查询活动下的商品信息
            if (Objects.nonNull(enroll.getId())) {
                ActivityPackageExportReqVO packageQuery = new ActivityPackageExportReqVO();
                packageQuery.setActiveId(createReqVO.getActivityId());
                List<ActivityPackageDO> packageDOList = packageService.getPackageList(packageQuery);
                if (!packageDOList.isEmpty()) {
                    packageDOList.forEach(item -> {
                        //保存相亲报名子表详情信息
                        ActivityEnrollVerificateCreateReqVO createVerificate = new ActivityEnrollVerificateCreateReqVO();
                        createVerificate.setActivityId(item.getActiveId());
                        createVerificate.setActivityProductsId(item.getProductId());
                        createVerificate.setUserId(createReqVO.getUserId());
                        createVerificate.setEnrollId(enroll.getId());
                        // 获得单个商品的单价
                        ProductInfoDO productInfoDO = productInfoService.getProductInfo(item.getProductId());
                        createVerificate.setPrice(new BigDecimal(productInfoDO.getPlatformPrice()));
                        Integer code = getReaptCode();
                        createVerificate.setVerificationCode(String.valueOf(code));
                        createVerificate.setStatus((byte) 0);
                        createVerificate.setType((byte) 0);
                        verificateService.createEnrollVerificate(createVerificate);
                    });
                }
            }
//            createPayOrder1(enroll);7
            // 返回
            return enroll;
        } catch (Exception ex) {
            // 发生异常时执行事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            throw ex;
        }
    }

    @Override
    public PayOrderSubmitRespVO createPayOrder(Long enrollId) {
        ActivityEnrollDO enroll = enrollMapper.selectById(enrollId);
        PayOrderSubmitRespVO respVO = new PayOrderSubmitRespVO();
        if (Objects.nonNull(enroll)) {
            //1.0 构建支付交易单
            PayOrderCreateReqDTO payOrder = new PayOrderCreateReqDTO();
            //1.1 获得相亲app的id
            PayAppDO payAppDO = payAppService.getApp(9L);
            if (Objects.nonNull(payAppDO)) {
                payOrder.setAppId(payAppDO.getId());
            } else {
                throw exception(PAY_ORDER_EXISTS);
            }
            payOrder.setBlindOrderId(enroll.getId());
            payOrder.setBlindOrderType(PayOrderTypeEnum.EVENT_REGISTRATION.getType());
            payOrder.setBody("会员报名活动缴费订单");

            payOrder.setMerchantOrderId(NoCommonUtil.getUuid(enroll.getId().toString()).toString());
            //1.2 将金额转成分
            BigDecimal cents = enroll.getPayAmount().multiply(new BigDecimal("100"));
            int intValue = cents.intValue();
            //TODO  测试： 1.2.1活动金额设置成1分
            payOrder.setPrice(1);
            payOrder.setSubject("活动报名缴费订单");
            //1.3 订单有效期
            LocalDateTime currentTime = LocalDateTime.now();
            LocalDateTime futureTime = currentTime.plusHours(12);
            payOrder.setExpireTime(futureTime);
            payOrder.setUserIp(getLoginUserId().toString());
            //2.0 创建支付交易单
            Long payOrderId = payOrderService.createOrder(payOrder);
            if (payOrderId != null) {
                //TODO 提交支付订单
                AppPayOrderSubmitReqVO reqVO = new AppPayOrderSubmitReqVO();
                reqVO.setId(payOrderId);
                if (enroll.getPayType() == 1) {
                    reqVO.setChannelCode("wx_app");
                } else {
                    reqVO.setChannelCode("alipay_app");
                }
                try {
                    respVO = payOrderService.submitOrder(reqVO, getClientIP());
                    log.info("支付成功-{}", respVO);
                } catch (Exception e) {
                    log.error("支付失败-{}", e.getMessage());
                }
            }
        }
        return respVO;
    }


    /**
     * 相亲业务-创建退款支付单
     */

    public PayOrderSubmitRespVO createPayOrder1231(ActivityEnrollDO enroll) {
        PayOrderSubmitRespVO respVO = new PayOrderSubmitRespVO();
        // 创建支付交易单
        PayOrderCreateReqDTO payOrder = new PayOrderCreateReqDTO();
        // 获得相亲app的id
        PayAppDO payAppDO = payAppService.getApp(9L);
        if (Objects.nonNull(payAppDO)) {
            payOrder.setAppId(payAppDO.getId());
        } else {
            throw exception(PAY_ORDER_EXISTS);
        }
        payOrder.setBlindOrderId(enroll.getId());
        payOrder.setBlindOrderType(2);
        payOrder.setBody("会员报名活动缴费订单");
        payOrder.setMerchantOrderId(enroll.getId().toString());
        payOrder.setPrice(enroll.getPayAmount().intValue());
        payOrder.setSubject("活动报名缴费订单");
        // 获取当前时间
        LocalDateTime currentTime = LocalDateTime.now();
        // 加上12小时
        LocalDateTime futureTime = currentTime.plus(12, ChronoUnit.HOURS);
        payOrder.setExpireTime(futureTime);
        payOrder.setUserIp(getLoginUserId().toString());

        Long payOrderId = payOrderService.createOrder(payOrder);
        if (payOrderId != null) {
            // 提交支付订单
            AppPayOrderSubmitReqVO reqVO = new AppPayOrderSubmitReqVO();
            reqVO.setId(payOrderId);
//            if (enroll.getPayType() == 1) {
//                reqVO.setChannelCode("wx_app");
//            } else {
//                reqVO.setChannelCode("alipay_app");
//            }
            reqVO.setChannelCode("mock");
            respVO = payOrderService.submitOrder(reqVO, getClientIP());
            if (Objects.nonNull(respVO)) {
                log.info("支付完成：支付回调{}", respVO);
//                System.out.println(respVO.getStatus() + "=====================" + respVO.getDisplayMode() + "=====================" + respVO.getDisplayContent());
            }


        }
        return respVO;
    }


    /**
     * 判重复并生成新的核销码
     *
     * @return
     */
    public int getReaptCode() {
        int randomNumber = 0;
        boolean isDuplicate = true;
        while (isDuplicate) {
            //生成核销码
            randomNumber = NoCommonUtil.getRandom();
            // 查找核销码是否重复
            Integer count = verificateMapper.getVerificationCode(String.valueOf(randomNumber));
            if (count == 0) {
                isDuplicate = false;
            }
        }
        return randomNumber;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateEnroll(ActivityEnrollUpdateReqVO updateReqVO) {
        // 校验存在
        validateEnrollExists(updateReqVO.getId());
        // 更新
        ActivityEnrollDO updateObj = ActivityEnrollConvert.INSTANCE.convert(updateReqVO);
        enrollMapper.updateById(updateObj);
    }

    @Override
    public void deleteEnroll(Long id) {
        // 校验存在
        validateEnrollExists(id);
        // 删除
        enrollMapper.deleteById(id);
    }

    private void validateEnrollExists(Long id) {
        if (enrollMapper.selectById(id) == null) {
            throw exception(ENROLL_NOT_EXISTS);
        }
    }

    @Override
    public ActivityEnrollDO getEnroll(Long id) {
        return enrollMapper.selectById(id);
    }

    @Override
    public List<ActivityEnrollDO> getEnrollList(Collection<Long> ids) {
        if (CollUtil.isEmpty(ids)) {
            return ListUtil.empty();
        }
        return enrollMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<ActivityEnrollDO> getEnrollPage(ActivityEnrollPageReqVO pageReqVO) {
        return enrollMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ActivityEnrollDO> getEnrollList(ActivityEnrollExportReqVO exportReqVO) {
        return enrollMapper.selectList(exportReqVO);
    }

    @Override
    public ActivityEnrollDO getEnrollByActiveId(String activityNo, Long userId) {
        LambdaQueryWrapper<ActivityEnrollDO> lqw = Wrappers.lambdaQuery();
        return enrollMapper.selectOne(lqw.eq(ActivityEnrollDO::getNo, activityNo)
                .eq(ActivityEnrollDO::getUserId, userId));
    }

    @Override
    public Integer enrollNum(Long activityId, Long userId) {
        return enrollMapper.enrollNum(activityId, userId);
    }

    @Override
    public Integer getNumber(Long activityId, Byte sex, Byte activityStatus) {
        return enrollMapper.getNumber(activityId, sex, activityStatus);
    }

    @Override
    public PageResult<T> getPageList(ActivityEnrollPageReqVO pageReqVO) {
        IPage<T> pageResult = enrollMapper.getPageList(MyBatisUtils.buildPage(pageReqVO), pageReqVO.getUserId());
        return new PageResult<>(pageResult.getRecords(), pageResult.getTotal());
    }

    /**
     * 男报名人员list
     */
    @Override
    public AppActivityInfoVo getEnrollPage(Long activityId, Long userId) {
        AppActivityInfoVo appActivityInfoVo = new AppActivityInfoVo();
        List<AppEnrollUseVO> menList = enrollMapper.getAllListNoSex(activityId, userId);
        List<Long> collect = menList.stream().map(AppEnrollUseVO::getUserId).collect(Collectors.toList());
        List<BlindMemberUserDO> memberUserList = memberUserService.getMemberUserList(collect);
        List<MemberUsertagDO> memberUsertagList = usertagService.getMemberUsertagList(new MemberUsertagExportReqVO());
        menList.stream().forEach(mem -> {
            //籍贯 所在地 中文
            String areaId = mem.getAreaId();
            if (Objects.nonNull(areaId) && StringUtils.isNotEmpty(areaId)) {
                String areaName = AreaUtils.getAreaName(areaId);
                if (StringUtils.isNotEmpty(areaName)) {
                    if (areaName.contains("/")) {
                        String midAreaName = areaName.substring(areaName.indexOf("/") + 1, areaName.lastIndexOf("/"));
                        mem.setAreaName(midAreaName);
                    }
                }
            }
            if (StringUtils.isNotBlank(mem.getIdNumber())) {
                mem.setIsIdCard(true);
            } else {
                mem.setIsIdCard(false);
            }

            mem.setSexName(dictDataService.getDictData("system_user_sex", String.valueOf(mem.getSex())).getLabel());
            if (StringUtils.isNotBlank(mem.getMonthIncome())) {
                mem.setMonthIncomeName(dictDataService.getDictData("matchIncome", mem.getMonthIncome()).getLabel());
            }
            if (mem.getPurchasCar() != null) {
                mem.setPurchasCarName(dictDataService.getDictData("purchase_car", String.valueOf(mem.getPurchasCar())).getLabel());
            }
            if (mem.getPurchasHouse() != null) {
                mem.setPurchasHouseName(dictDataService.getDictData("purchase_situation", String.valueOf(mem.getPurchasHouse())).getLabel());
            }
//            星座
            if (Objects.nonNull(memberUserList)) {
                BlindMemberUserDO blindMemberUserDO = memberUserList.stream().filter(s -> s.getId().equals(mem.getUserId())).findFirst().orElse(null);
                if (Objects.nonNull(blindMemberUserDO)) {
//                    星座
                    if (StringUtils.isNotEmpty(blindMemberUserDO.getConstellation())) {
                        mem.setConstellation(blindMemberUserDO.getConstellation());
                    }
//                    标签
                    if (CollectionUtils.isNotEmpty(memberUsertagList)) {
                        List<MemberUsertagDO> collectTag = memberUsertagList.stream().filter(s -> s.getUserId().equals(blindMemberUserDO.getId())).collect(Collectors.toList());
                        if (CollectionUtils.isNotEmpty(collectTag)) {
                            mem.setUsertag(collectTag);
                        }
                    }
                }
            }
        });
        appActivityInfoVo.setEnrollMenList(menList);
        return appActivityInfoVo;
    }

    @Override
    public Integer getEnrollNum() {
        Integer r = enrollMapper.getEnrollNum();
        return r;
    }

    @Override
    public Byte getMemberSex(Long userId) {
        return enrollMapper.getMemberSex(userId);
    }


    /**
     * 获得报名记录
     *
     * @param query
     * @return
     */
    @Override
    public List<EnrollUseVO> getActivityEnrollList(ActivityEnrollQueryVO query) {
        return enrollMapper.getActivityEnrollList(query);
    }

    @Override
    public List<ActivityEnrollDO> selectEnrollList(ActivityEnrollQueryVO reqVO) {
        return enrollMapper.selectEnrollList(reqVO);
    }

    @Override
    public ActivityEnrollDO getSelectOne(Long activityId, Long userId, Byte status) {
        LambdaQueryWrapper<ActivityEnrollDO> lqw = Wrappers.lambdaQuery();
        return enrollMapper.selectOne(lqw.eq(ActivityEnrollDO::getActivityId, activityId)
                .eq(ActivityEnrollDO::getUserId, userId)
                .eq(ActivityEnrollDO::getStatus, status));
    }

    @Override
    public BigDecimal getActivityIdAmount(Long activityId) {
        return enrollMapper.getActivityIdAmount(activityId);
    }

    @Override
    public int updatePayStatus(Long id, Byte status) {
        return enrollMapper.update(null, new LambdaUpdateWrapper<ActivityEnrollDO>()
                .set(ActivityEnrollDO::getStatus, status)
                .eq(ActivityEnrollDO::getId, id));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void notifyEnroll(Long channelId, PayOrderRespDTO notify) {
        PayChannelDO payChannelDO = channelService.getChannel(channelId);
        // 情况一：支付成功的回调
        if (PayOrderStatusRespEnum.isSuccess(notify.getStatus())) {
            // 1. 查询 PayOrderExtensionDO
            PayOrderExtensionDO orderExtension = orderExtensionMapper.selectByNo(notify.getOutTradeNo());
            // 2. 通过 PayOrderExtensionDO 查询PayOrderDO 来 判断 PayOrderDO 是否存在
            PayOrderDO order = orderMapper.selectById(orderExtension.getOrderId());

            if (Objects.nonNull(order)) {
                if (PayOrderTypeEnum.EVENT_REGISTRATION.getType().equals(order.getBlindOrderType())) {
                    log.info("活动报名回调：{}", notify);
                    ActivityEnrollDO enrollDO = enrollMapper.selectById(order.getBlindOrderId());
                    if (Objects.nonNull(enrollDO)) {
                        ActivityInfoDO activityInfoDO = activityInfoMapper.selectById(enrollDO.getActivityId());
                        // 2.1活动创建者更新活动的状态
                        if (Objects.equals(enrollDO.getUserId(), activityInfoDO.getHeadUserId())) {
                            //2.2 更新活动状态
                            byte b = (byte) 1;
                            if (activityInfoDO.getStatus().equals(b)) {
                                log.info("更新活动状态：{}", activityInfoDO);
                                activityInfoMapper.update(null, new LambdaUpdateWrapper<ActivityInfoDO>()
                                        .set(ActivityInfoDO::getStatus, 0)
                                        .eq(ActivityInfoDO::getId, activityInfoDO.getId()));
                            }
                            // 2.3 更新报名状态为已报名，只为-1的报名状态修改为已报名
                            byte status = (byte) 1;
                            if (enrollDO.getStatus().equals(status)) {
                                log.info("更新报名状态：{}", enrollDO);
                                enrollMapper.update(null, new LambdaUpdateWrapper<ActivityEnrollDO>()
                                        .set(ActivityEnrollDO::getStatus, 0)
                                        .eq(ActivityEnrollDO::getId, order.getBlindOrderId()));
                            }
                        }else {
                            // 2.3 更新报名状态为已报名，只为-1的报名状态修改为已报名
                            byte b = (byte) -1;
                            if (enrollDO.getStatus().equals(b)) {
                                log.info("更新报名状态：{}", enrollDO);
                                enrollMapper.update(null, new LambdaUpdateWrapper<ActivityEnrollDO>()
                                        .set(ActivityEnrollDO::getStatus, 0)
                                        .eq(ActivityEnrollDO::getId, order.getBlindOrderId()));
                            }
                        }
                    }
                }
            } else {
                log.error("未找到活动报名的支付订单：{}", notify);
            }
        }
        // 情况二：支付失败的回调
        if (PayOrderStatusRespEnum.isClosed(notify.getStatus())) {
            notifyOrderClosed(payChannelDO, notify);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void notifyRefundEnroll(Long channelId, PayRefundRespDTO notify) {
        // 情况一：退款成功
        if (PayRefundStatusRespEnum.isSuccess(notify.getStatus())) {
            // 1.查询支付渠道
            PayChannelDO channel = channelService.validPayChannel(channelId);
            // 1.1 查询 PayRefundDO
            PayRefundDO refund = refundMapper.selectByAppIdAndNo(
                    channel.getAppId(), notify.getOutRefundNo());
            if (Objects.nonNull(refund)) {
                //2.1 根据退款单查找相对应的支付单
                PayOrderDO order = orderMapper.selectById(refund.getOrderId());
                //3.2 更新业务状态
                if (PayOrderTypeEnum.EVENT_REGISTRATION.getType().equals(order.getBlindOrderType())) {
                    ActivityEnrollDO enrollDO = enrollMapper.selectById(order.getBlindOrderId());
                    //3.1更新报名状态,已退回
                    enrollMapper.update(null, new LambdaUpdateWrapper<ActivityEnrollDO>()
                            .set(ActivityEnrollDO::getStatus, 2)
                            .eq(ActivityEnrollDO::getId, order.getBlindOrderId()));
                    //3.2更新活动状态，已驳回
                    activityInfoMapper.update(null, new LambdaUpdateWrapper<ActivityInfoDO>()
                            .set(ActivityInfoDO::getStatus, 6)
                            .eq(ActivityInfoDO::getId, enrollDO.getActivityId()));
                }
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void createEnrollRefund(List<ActivityEnrollDO> list) {
        if (!list.isEmpty()) {
            list.forEach(item -> {

            });
        }
    }

    @Override
    public void updateActivityStatus(Long activityId, Byte sex, int num) {
        // 分批更新数据
        for (int i = 0; i < num; i += num) {
            enrollMapper.update(null, new LambdaUpdateWrapper<ActivityEnrollDO>()
                    .set(ActivityEnrollDO::getActivityStatus, 0)
                    .eq(ActivityEnrollDO::getActivityStatus, 1)
                    .eq(ActivityEnrollDO::getActivityId, activityId)
                    .eq(ActivityEnrollDO::getSex, sex)
                    .eq(ActivityEnrollDO::getStatus, 0)
                    .orderByAsc(ActivityEnrollDO::getCreateTime));
        }
    }

    private void notifyOrderClosed(PayChannelDO channel, PayOrderRespDTO notify) {
        updateOrderExtensionClosed(channel, notify);
    }

    private void updateOrderExtensionClosed(PayChannelDO channel, PayOrderRespDTO notify) {
        // 1. 查询 PayOrderExtensionDO
        PayOrderExtensionDO orderExtension = orderExtensionMapper.selectByNo(notify.getOutTradeNo());
        if (orderExtension == null) {
            throw exception(PAY_ORDER_EXTENSION_NOT_FOUND);
        }
        if (PayOrderStatusEnum.isClosed(orderExtension.getStatus())) { // 如果已经是关闭，直接返回，不用重复更新
            log.info("[updateOrderExtensionClosed][orderExtension({}) 已经是支付关闭，无需更新]", orderExtension.getId());
            return;
        }
        // 一般出现先是支付成功，然后支付关闭，都是全部退款导致关闭的场景。这个情况，我们不更新支付拓展单，只通过退款流程，更新支付单
        if (PayOrderStatusEnum.isSuccess(orderExtension.getStatus())) {
            log.info("[updateOrderExtensionClosed][orderExtension({}) 是已支付，无需更新为支付关闭]", orderExtension.getId());
            return;
        }
        if (ObjectUtil.notEqual(orderExtension.getStatus(), PayOrderStatusEnum.WAITING.getStatus())) { // 校验状态，必须是待支付
            throw exception(PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING);
        }

        // 2. 更新 PayOrderExtensionDO
        int updateCounts = orderExtensionMapper.updateByIdAndStatus(orderExtension.getId(), orderExtension.getStatus(),
                PayOrderExtensionDO.builder().status(PayOrderStatusEnum.CLOSED.getStatus()).channelNotifyData(toJsonString(notify))
                        .channelErrorCode(notify.getChannelErrorCode()).channelErrorMsg(notify.getChannelErrorMsg()).build());
        if (updateCounts == 0) { // 校验状态，必须是待支付
            throw exception(PAY_ORDER_EXTENSION_STATUS_IS_NOT_WAITING);
        }
        log.info("[updateOrderExtensionClosed][orderExtension({}) 更新为支付关闭]", orderExtension.getId());
    }


    /**
     * 获得自身的代理对象，解决 AOP 生效问题
     *
     * @return 自己
     */
    private ActivityEnrollServiceImpl getSelf() {
        return SpringUtil.getBean(getClass());
    }


}
